package com.qf.config;

import com.qf.entity.SysMenu;
import com.qf.mapper.SysMenuDao;
import com.qf.mapper.SysMenuMapper;
import com.qf.security.handlers.MyAuthedSuccessHandler;
import com.qf.security.handlers.MyLoginFailureHandler;
import com.qf.security.service.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @Author ztf
 * @Date 20:35 2022/1/11
 **/
@EnableWebSecurity //开启spring security
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    private MyUserDetailService myUserDetailService;

    private BCryptPasswordEncoder bCryptPasswordEncoder;

    private MyLoginFailureHandler myLoginFailureHandler;

    private MyAuthedSuccessHandler myAuthedSuccessHandler;

    private SysMenuDao sysMenuDao;

    private SysMenuMapper sysMenuMapper;

    @Autowired
    public void setMyUserDetailService(MyUserDetailService myUserDetailService) {
        this.myUserDetailService = myUserDetailService;
    }

    @Autowired
    public void setbCryptPasswordEncoder(BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @Autowired
    public void setMyLoginFailureHandler(MyLoginFailureHandler myLoginFailureHandler) {
        this.myLoginFailureHandler = myLoginFailureHandler;
    }

    @Autowired
    public void setMyAuthedSuccessHandler(MyAuthedSuccessHandler myAuthedSuccessHandler) {
        this.myAuthedSuccessHandler = myAuthedSuccessHandler;
    }

    @Autowired
    public void setSysMenuDao(SysMenuDao sysMenuDao) {
        this.sysMenuDao = sysMenuDao;
    }

    @Autowired
    public void setSysMenuMapper(SysMenuMapper sysMenuMapper) {
        this.sysMenuMapper = sysMenuMapper;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        //忽略掉不想拦截的地址
        web.ignoring().antMatchers("/index.html", "/css/**", "/js/**", "/websocket/*",
                "/humiture/*");
        super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //允许跨域
        http.csrf().disable();
        List<SysMenu> sysMenus = sysMenuDao.selectByExample(null);
        sysMenus.parallelStream().filter(menu -> StringUtils.hasText(menu.getUrl())).forEach(menu -> {
            try {
                http.authorizeRequests().antMatchers(menu.getUrl()).hasAnyAuthority(menu.getPerms());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        http.authorizeRequests()//开始认证琴秋
                // .and().formLogin()
                //设置登录失败之后怎么办
                .and().formLogin().failureHandler(myLoginFailureHandler)
                //自定义成功的处理器
                .successHandler(myAuthedSuccessHandler)
                //这个地址实际上是springsecurity处理的,不用我们单独写这个地址
                .loginProcessingUrl("/login")
                //放行登录地址
                .permitAll()
                //任意地址
                .and().authorizeRequests().anyRequest()
                .authenticated();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailService).passwordEncoder(bCryptPasswordEncoder);
    }
}
